home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CUJ9202.ARJ / 1002069A < prev    next >
Text File  |  1992-06-02  |  11KB  |  437 lines

  1.  
  2.  
  3.  
  4.        /******************************************************
  5.        *
  6.        *       file d:\lsu\cujhuff4.c
  7.        *
  8.        *****************************************************/
  9.  
  10.  
  11. #include "d:\lsu\cujhuff.h"
  12.  
  13.  
  14. /* 
  15.     decode_compressed_file(...
  16.  
  17.     This is the main function of the decompression
  18.     portion of the program.
  19.  
  20. */
  21.  
  22. decode_compressed_file(input_file_name, output_file_name, 
  23.                        item_array, file_header)
  24.    char   input_file_name[], output_file_name[];
  25.    struct item_struct item_array[];
  26.    struct header_struct *file_header;
  27. {
  28.    char r[80];
  29.    int  in_file_desc,
  30.         out_file_desc;
  31.  
  32.    open_files_for_decode(input_file_name, output_file_name,
  33.                          &in_file_desc, &out_file_desc);
  34.  
  35.    input_file_header(file_header, in_file_desc);
  36.    convert_short_to_long(item_array, file_header);
  37.  
  38.    decode_file_and_write_output(item_array, 
  39.                                 in_file_desc, 
  40.                                 out_file_desc);
  41.  
  42.    close_decode_files(in_file_desc, out_file_desc);
  43.  
  44.  
  45. }  /* ends decode_compressed_file */
  46.  
  47.  
  48.  
  49. /*    
  50.          open_files_for_decode(...
  51.  
  52.          Open the input and output file.
  53. */
  54.  
  55.  
  56. open_files_for_decode(in_file_name, out_file_name, 
  57.                       in_file_desc, out_file_desc)
  58.    char in_file_name[], out_file_name[];
  59.    int        *in_file_desc, *out_file_desc;
  60.  
  61. {
  62.    int a ,b;
  63.  
  64.    *out_file_desc = open(out_file_name, O_RDWR | O_CREAT | O_BINARY,
  65.                          S_IWRITE);
  66.    *in_file_desc  = open(in_file_name, O_RDWR | O_CREAT | O_BINARY,
  67.                          S_IWRITE);
  68.  
  69. }  /*  ends open_files_for_decode        */
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77. /*  
  78.            input_file_header(file_header, in_file_desc)
  79.  
  80.            This function reads in the short header from the
  81.            front of the input file.
  82. */
  83.  
  84.  
  85. input_file_header(file_header, in_file_desc)
  86.    int    in_file_desc;
  87.    struct header_struct *file_header;
  88. {
  89.         int     bytes_read,
  90.                 i;
  91.  
  92.         char    in_buffer[(sizeof(struct header_struct))],
  93.                 *charptr,
  94.                 name[80];
  95.  
  96.         long    position;
  97.  
  98.  
  99.         position   = lseek(in_file_desc, 0L, 0);
  100.         bytes_read = my_read(in_file_desc, in_buffer, 
  101.                              sizeof(struct header_struct));
  102. /*printf("\n\n> Read %d bytes using file header", bytes_read);*/
  103.  
  104.         charptr = (char *)file_header;
  105.         for(i=0; i<((sizeof(struct header_struct))); i++)
  106.            *charptr++ = in_buffer[i];
  107.  
  108. }       /* ends input_item_array  */
  109.    
  110.  
  111.  
  112.  
  113.  
  114.  
  115. /* 
  116.         decode_file_and_write_output(...
  117.  
  118.         This function takes in the packed bits, decodes them,
  119.         and puts the decoded characters out to the output
  120.         file.
  121.  
  122. */
  123.  
  124.  
  125. decode_file_and_write_output(item_array, in_file_desc, out_file_desc)
  126.    int    in_file_desc, out_file_desc;
  127.    struct item_struct item_array[];
  128. {
  129.    char  output_buffer[IB_LENGTH],
  130.          r[80],
  131.          stream_buffer[CODE_LENGTH],
  132.          stream_of_bits[OB_LENGTH];
  133.  
  134.    int   bytes_read,
  135.          counter,
  136.          i,
  137.          in_disp,
  138.          not_finished,
  139.          output_pointer,
  140.          stream_pointer;
  141.    counter        = 0;
  142.    output_pointer = 0;
  143.    stream_pointer = 0;
  144.    bytes_read     = 0;
  145.    not_finished   = 1;
  146.  
  147.    for(i=0; i<IB_LENGTH; i++)
  148.       output_buffer[i] = OTHER;
  149.  
  150.    while(not_finished){
  151.  
  152.       read_in_buffer(in_file_desc, in_disp, 
  153.                      stream_of_bits, &bytes_read);
  154.  
  155. /*printf("\n> read %d bytes into stream of bits", bytes_read);*/
  156.       stream_pointer = 0;
  157.  
  158.       if(bytes_read < OB_LENGTH)
  159.          not_finished = 0;
  160.  
  161.          /* work through the stream_of_bits
  162.             you're finished when the stream_pointer
  163.             equals bytes_read * 8 bits per byte. */
  164.  
  165.       while(stream_pointer < bytes_read*8){
  166.          convert_bits_to_char(stream_of_bits, stream_pointer, 
  167.                                  stream_buffer);
  168.    
  169.          decode_bits(stream_buffer, item_array, 
  170.                      output_buffer, &output_pointer,
  171.                      &stream_pointer);
  172.  
  173. /*printf("\n> stream pointer = %d", stream_pointer);*/
  174.             /* if output_buffer fills up write it to disk */
  175.          if(output_pointer >= IB_LENGTH-10){
  176.             counter++;
  177.             printf("\n> Writing to output file-%d", counter);
  178.             write_out_buffer(out_file_desc, 
  179.                              output_buffer, 
  180.                              output_pointer);
  181.             output_pointer = 0;
  182.  
  183.          }  /* ends if output_pointer is too big */
  184.       }     /* ends while stream_pointer < bytes_read*8 */
  185.  
  186.    }  /* ends while not_finished */
  187.  
  188.    if(output_pointer > 0){
  189.          printf("\n> Writing to output file");
  190.          write_out_buffer(out_file_desc, output_buffer, output_pointer);
  191.    }
  192.  
  193. }  /* ends decode_file_and_write_output */
  194.    
  195.  
  196.  
  197.  
  198.  
  199. /* 
  200.           read_in_buffer(...
  201.  
  202.           This function reads the input file and puts the packed
  203.           bits into the stream_of_bits.
  204. */
  205.  
  206. read_in_buffer(in_file_desc, in_disp, stream_of_bits, 
  207.                bytes_read)
  208.    int   *bytes_read, in_file_desc, in_disp;
  209.    char  stream_of_bits[];
  210. {
  211.    int b;
  212.  
  213.    for(b=0; b<OB_LENGTH; b++)
  214.       stream_of_bits[b] = 0x00;
  215.  
  216.    *bytes_read = read(in_file_desc, stream_of_bits, OB_LENGTH);
  217.  
  218. }  /* ends read_in_buffer */
  219.  
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226. /* 
  227.           convert_bits_to_char(...
  228.  
  229.           This function takes the next CODE_LENGTH # of bits
  230.           from the stream_of_bits and converts them to bytes
  231.           having the value ONE or ZERO.  These bytes are placed
  232.           into the stream_buffer.  This makes it easier for
  233.           the decode_bits function to compare coded with the
  234.           packed bits.
  235. */
  236.  
  237.  
  238. convert_bits_to_char(stream_of_bits, stream_pointer, stream_buffer)
  239.    char  stream_of_bits[], stream_buffer[];
  240.    int   stream_pointer;
  241. {
  242.    char temp;
  243.  
  244.  
  245.    int bit_in_byte, 
  246.        byte_in_buffer, 
  247.        i,
  248.        j;
  249.  
  250.  
  251.    for(i=0; i<CODE_LENGTH; i++)
  252.       stream_buffer[i] = OTHER;
  253.  
  254.    j = -1;
  255.  
  256.    for(i=stream_pointer; i<stream_pointer+CODE_LENGTH; i++){
  257.  
  258.       j++;
  259.       bit_in_byte    = i % 8;
  260.       byte_in_buffer = i/8;
  261.  
  262.          /* Test the bit by shifting it to the left
  263.             by the number bit_in_byte and then ANDing
  264.             it with 1000 0000 (128).
  265.             For this routine bit zero is the left most
  266.             or most significant bit of temp */
  267.  
  268.       temp = stream_of_bits[byte_in_buffer];
  269.       temp = temp << bit_in_byte;
  270.       if((temp & SET_BIT_ZERO) != 0)
  271.          stream_buffer[j] = ONE;
  272.       else
  273.          stream_buffer[j] = ZERO;
  274.  
  275.    }  /* ends loop over i */
  276.  
  277. }  /* ends convert_bits_to_char */
  278.  
  279.  
  280.  
  281. /* 
  282.           decode_bits(...
  283.  
  284.           Look at the converted bits from the packed file
  285.           compare them to the item_array.coded (start looking
  286.           at the top of the item_array since those occur most
  287.           frequently) and put the original character in the 
  288.           output buffer
  289. */
  290.  
  291. decode_bits(stream_buffer, item_array, 
  292.             output_buffer, output_pointer,
  293.             stream_pointer)
  294.    char output_buffer[], stream_buffer[];
  295.    int  *output_pointer, *stream_pointer;
  296.    struct item_struct item_array[];
  297. {
  298.    int   found,
  299.          i,
  300.          j,
  301.          length_of_code,
  302.          not_finished;
  303.  
  304.  
  305.    char  compare_string[CODE_LENGTH], r[80];
  306.  
  307.    found        = 0;
  308.    not_finished = 1;
  309.    j            = 0;
  310.  
  311.       /* search through the item_array looking for a coded array that
  312.          matches the characters in the stream_buffer 
  313.          If you find it, increase the stream_pointer by
  314.          adding length_of_code to it. */
  315.  
  316.    while(not_finished){
  317.  
  318.       extract_code(item_array[j].coded, compare_string, &length_of_code);
  319.  
  320.       if(strncmp(compare_string, 
  321.                  stream_buffer,       
  322.                  length_of_code) == 0){
  323.          found        = 1;
  324.          not_finished = 0;
  325.          *stream_pointer = *stream_pointer + length_of_code;
  326.       }  /* ends if strncmp */
  327.  
  328.       else{   /* did not find the code so keep looking */
  329.          j++;
  330.          if(j > LENGTH){
  331.             not_finished = 0;
  332.             printf("\n\n\t> FAILURE - did not find code\n\n");
  333.          }
  334.       }  /* ends else */
  335.  
  336.    }  /* ends while not_finished */
  337.  
  338.       /* now put the decoded character in to the output_buffer */
  339.  
  340.    if(found == 1){
  341.       output_buffer[*output_pointer] = item_array[j].character;
  342.       *output_pointer = *output_pointer + 1;
  343.    }  /* ends if found == 1 */
  344.  
  345. }  /* ends decode_bits */
  346.  
  347.  
  348.  
  349.  
  350.  
  351. /* 
  352.             extract_code(...
  353.  
  354.             Pull the code out of item_array[x].coded,
  355.             put it into compare_string, and put the
  356.             length of the code into length.
  357. */
  358.  
  359. extract_code(coded, compare_string, length_of_code)
  360.    char coded[], compare_string[];
  361.    int  *length_of_code;
  362. {
  363.    int  i, j, k, m, not_finished;
  364.  
  365.  
  366.       /* clear the compare_string */
  367.    for(k=0; k<CODE_LENGTH; k++)
  368.       compare_string[k] = OTHER;
  369.  
  370.    not_finished    = 1;
  371.    *length_of_code = 0;
  372.    i               = CODE_LENGTH-1;
  373.    j               = 0;
  374.  
  375.       /* Start at the end of coded and search back until you
  376.          run out of code i.e. you hit a OTHER. */
  377.  
  378.    while(not_finished){
  379.       if(coded[i] != OTHER){
  380.          i--;
  381.          j++;
  382.       }
  383.       else
  384.          not_finished = 0;
  385.    }  /* ends while not_finished */
  386.  
  387.       /* adjust value of i */
  388.    i++;
  389.  
  390.       /* Copy the coded to the compare_string */
  391.    *length_of_code = j;
  392.    m       = 0;
  393.    for(k=i; k<CODE_LENGTH; k++){
  394.       compare_string[m] = coded[k];
  395.       m++;
  396.    }
  397.  
  398. }  /* ends extract_code */
  399.  
  400.  
  401.  
  402.  
  403. /* 
  404.           write_out_buffer(...
  405.  
  406.           Write the output_buffer to file.
  407. */
  408.  
  409. write_out_buffer(out_file_desc, output_buffer, output_pointer)
  410.    char output_buffer[];
  411.    int  out_file_desc, output_pointer;
  412. {
  413.    int bytes_written;
  414.  
  415.    bytes_written = 
  416.      my_write(out_file_desc, output_buffer, output_pointer);
  417. }  /* ends write_out_buffer */
  418.  
  419.  
  420.  
  421. /* 
  422.           close_decode_files(...
  423.  
  424.           Close the files.
  425. */
  426.  
  427.  
  428. close_decode_files(in_file_desc, out_file_desc)
  429.    int in_file_desc, out_file_desc;
  430. {
  431.  
  432.    close(in_file_desc);
  433.    close(out_file_desc);
  434.  
  435. } /* ends close_decode_files */
  436. /* End of File */
  437.